package net.wanho.shop.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.RequiredArgsConstructor;
import net.wanho.shop.common.CaptchaConstant;
import net.wanho.shop.common.UserConstant;
import net.wanho.shop.dto.LoginUserDTO;
import net.wanho.shop.exception.LoginErrorException;
import net.wanho.shop.mapper.RoleMapper;
import net.wanho.shop.mapper.UserMapper;
import net.wanho.shop.po.Role;
import net.wanho.shop.po.User;
import net.wanho.shop.service.LoginService;
import net.wanho.shop.util.JwtUtil;
import net.wanho.shop.vo.CaptchaVo;
import net.wanho.shop.vo.LoginUserVo;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 这个类是：
 *
 * @author: MENG HU WANG
 * @date: 2024/12/24 21:58
 * @version: 1.0
 */

@Service
@RequiredArgsConstructor
public class LoginServiceImpl implements LoginService {

    private final UserMapper userMapper;
    private final RoleMapper roleMapper;
    private final StringRedisTemplate redisTemplate;


    @Override
    public LoginUserVo login(LoginUserDTO loginUserDTO) {
        // 1. 根据用户名查询用户
        User user = userMapper.selectByUserName(loginUserDTO.getUsername());
        // 2. 判断用户是否存在
        if (user == null) {
            throw new LoginErrorException("用户不存在");
        }
        // 3. 判断密码是否正确
        if (!user.getPassword().equals(SecureUtil.md5(loginUserDTO.getPassword()))) {
            throw new LoginErrorException("密码错误");
        }
        // 4. 判断用户是否被禁用
        if (Objects.equals(user.getMgState(), UserConstant.STATE_DISABLE)) {
            throw new LoginErrorException("用户被禁用");
        }
        // 5.生成token
        Map<String, Object> payload = new HashMap<>();
        payload.put(UserConstant.USER_ID, user.getId());
        payload.put(UserConstant.USER_NAME, user.getUsername());
        String token = JwtUtil.generate(payload);

        LoginUserVo loginUserVo = new LoginUserVo();
        // 6.拷贝属性
        BeanUtils.copyProperties(user, loginUserVo);
        // 7.设置token
        loginUserVo.setToken("Bearer " + token);
        // 8.查询角色名称
        Role role = roleMapper.selectById(user.getRoleId());
        loginUserVo.setRoleName(role.getRoleName());

        return loginUserVo;
    }


    @Override
    public CaptchaVo captcha() {
        // 生成验证码
        Captcha captcha = new ArithmeticCaptcha(); // 算术验证码
        SpecCaptcha captcha2 = new SpecCaptcha(100, 40, 4);

        // 生成一个临时用户id，对应用户的验证码
        String uuid = IdUtil.simpleUUID();
        String img = captcha.toBase64();
        String code = captcha.text();

        // 将验证码保存到redis中
        redisTemplate.opsForValue().set(CaptchaConstant.CAPTCHA_PREFIX + uuid, code,
                CaptchaConstant.CAPTCHA_EXPIRE, TimeUnit.MINUTES);

        CaptchaVo captchaVo = new CaptchaVo();
        captchaVo.setUuid(uuid);
        captchaVo.setImg(img);

        return captchaVo;
    }

    @Override
    public LoginUserVo captchaLogin(LoginUserDTO loginUserDTO) {
        // 判断验证码
        // 获取redis中的验证码
        String key = CaptchaConstant.CAPTCHA_PREFIX + loginUserDTO.getUuid();
        String trueCode = redisTemplate.opsForValue().get(key);
        if (ObjectUtils.isEmpty(trueCode)) {
            throw new RuntimeException("验证码已过期");
        }
        // 删除验证码
        redisTemplate.delete(key);
        if (!trueCode.equals(loginUserDTO.getCode())) {
            throw new RuntimeException("验证码错误");
        }
        return login(loginUserDTO);
    }
}
